package com.mys.maggie.redis.api.util;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.mys.maggie.redis.api.config.MagRedisProperties;
import com.mys.maggie.redis.api.enums.SerializerTypeEnum;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.util.ArrayList;
import java.util.List;

/**
 * desc: string帮助类型
 * date:2020/9/24 14:27
 */
public class RedisHelpUtil {

    /**
     * 交换对象。当前值为空，则取后面的值
     * @param present 当前值
     * @param target 目标值
     * @return 不为空的值
     */
    public static Integer swapIfPresentIsNull(Integer present, Integer target){
        if (present==null){
            return target;
        }
        return present;
    }

    /**
     * 交换对象。当前值为空，则取后面的值
     * @param present 当前值
     * @param target 目标值
     * @return 不为空的值
     */
    public static Integer swapIfPresentIsNull(Integer present, Integer target, Integer defaultValue){
        if (present==null && target==null &&  defaultValue != null){
            return defaultValue;
        }
        if (present!=null){
            return present;
        }
        if ( target != null){
            return target;
        }
        return defaultValue;
    }

    /**
     * 节点转换
     * @param nodes 节点
     * @return List<RedisNode>
     */
    public static List<RedisNode> convertRedisNodeList(List<String> nodes) {
        List<RedisNode> nodeList = new ArrayList<>();
        nodes.forEach(nodeAndPort->{
            String[] ipArr = nodeAndPort.split(":");
            if (ipArr.length < 2){
                System.out.println("redis ip 配置错误，nodeAndPort="+nodeAndPort);
                return;
            }
            RedisNode redisNode =new RedisNode(ipArr[0], Integer.parseInt(ipArr[1]));
            nodeList.add( redisNode);
        });

        return nodeList;
    }

    /**
     * 初始化 RedisTemplate实例
     * 1、key使用 StringRedisSerializer 序列化方式
     * 2、其他
     * @param connectionFactory 链接工厂
     * @return RedisTemplate
     */
    public static RedisTemplate<String, Object> buildRedisTemplate(RedisConnectionFactory connectionFactory,
                                                                   MagRedisProperties.Cluster cluster, MagRedisProperties properties){
        //1、设置ObjectMapper
        //2、设置Jackson2JsonRedisSerializer
        //3、设置RedisSerializer
        //4、设置RedisTemplate
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisTemplate<String, Object> template = new RedisTemplate<>();

        Integer keyEnumType = swapIfPresentIsNull(cluster.getKeySerializer(),properties.getKeySerializer(),
                                 SerializerTypeEnum.StringRedisSerializerEnum.getType() );
        Integer valueEnumType = swapIfPresentIsNull(cluster.getValueSerializer(),properties.getValueSerializer(),
                                SerializerTypeEnum.GenericJackson2JsonRedisSerializerEnum.getType() );
        Integer hashKeyEnumType = swapIfPresentIsNull(cluster.getHashKeySerializer(),properties.getHashKeySerializer(),
                                SerializerTypeEnum.GenericJackson2JsonRedisSerializerEnum.getType() );
        Integer hashValueEnumType = swapIfPresentIsNull(cluster.getHashValueSerializer(),properties.getHashValueSerializer(),
                                SerializerTypeEnum.GenericJackson2JsonRedisSerializerEnum.getType() );
        //中转赋值
        RedisSerializer keySerializer = RedisSerializerUtil.getRedisSerializer(keyEnumType, jackson2JsonRedisSerializer);
        RedisSerializer valueSerializer = RedisSerializerUtil.getRedisSerializer(valueEnumType , jackson2JsonRedisSerializer);
        RedisSerializer hashKeySerializer = RedisSerializerUtil.getRedisSerializer(hashKeyEnumType , jackson2JsonRedisSerializer);
        RedisSerializer hashValueSerializer = RedisSerializerUtil.getRedisSerializer(hashValueEnumType, jackson2JsonRedisSerializer);

        template.setKeySerializer( keySerializer );
        template.setValueSerializer( valueSerializer );
        template.setHashKeySerializer( hashKeySerializer );
        template.setHashValueSerializer( hashValueSerializer );

        template.setConnectionFactory(connectionFactory);
        template.afterPropertiesSet();

        return template;
    }



}
